{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import torch\n",
    "import numpy as np\n",
    "from PIL import Image\n",
    "import sys "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "# ground truth\n",
    "gt_paths = []\n",
    "path = '/root/haiquanLu/data/SOD/data/ECSSD'\n",
    "data_list = '../data/ECSSD/test_gt.lst'\n",
    "with open(data_list, 'r') as f:\n",
    "    image_list = [x.strip() for x in f.readlines()]\n",
    "gt_list = sorted(image_list)\n",
    "for i in range(len(gt_list)):\n",
    "    gt_paths.append(os.path.join(path, gt_list[i]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# pred\n",
    "\n",
    "pred_paths = []\n",
    "path = './results/run-0-sal-e' # predicted image directory\n",
    "test_pred = sorted(os.listdir(path))\n",
    "for i in range(len(test_pred)):\n",
    "    pred_paths.append(os.path.join(path, test_pred[i]))\n",
    "\n",
    "pred_paths = sorted(pred_paths)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def prec_rec(y_true, y_pred, beta2):\n",
    "    \n",
    "    eps = sys.float_info.epsilon\n",
    "    tp = torch.sum(y_true * y_pred)\n",
    "    all_p_pred = torch.sum(y_pred)\n",
    "    all_p_true = torch.sum(y_true)\n",
    "    \n",
    "    prec = (tp + eps) / (all_p_pred + eps)\n",
    "    rec = (tp + eps) / (all_p_true + eps)\n",
    "    # print(prec)\n",
    "    # print(rec)\n",
    "    \n",
    "    return prec, rec"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n",
      "9\n",
      "10\n",
      "11\n",
      "12\n",
      "13\n",
      "14\n",
      "15\n",
      "16\n",
      "17\n",
      "18\n",
      "19\n",
      "20\n",
      "21\n",
      "22\n",
      "23\n",
      "24\n",
      "25\n",
      "26\n",
      "27\n",
      "28\n",
      "29\n",
      "30\n",
      "31\n",
      "32\n",
      "33\n",
      "34\n",
      "35\n",
      "36\n",
      "37\n",
      "38\n",
      "39\n",
      "40\n",
      "41\n",
      "42\n",
      "43\n",
      "44\n",
      "45\n",
      "46\n",
      "47\n",
      "48\n",
      "49\n",
      "50\n",
      "51\n",
      "52\n",
      "53\n",
      "54\n",
      "55\n",
      "56\n",
      "57\n",
      "58\n",
      "59\n",
      "60\n",
      "61\n",
      "62\n",
      "63\n",
      "64\n",
      "65\n",
      "66\n",
      "67\n",
      "68\n",
      "69\n",
      "70\n",
      "71\n",
      "72\n",
      "73\n",
      "74\n",
      "75\n",
      "76\n",
      "77\n",
      "78\n",
      "79\n",
      "80\n",
      "81\n",
      "82\n",
      "83\n",
      "84\n",
      "85\n",
      "86\n",
      "87\n",
      "88\n",
      "89\n",
      "90\n",
      "91\n",
      "92\n",
      "93\n",
      "94\n",
      "95\n",
      "96\n",
      "97\n",
      "98\n",
      "99\n",
      "100\n",
      "101\n",
      "102\n",
      "103\n",
      "104\n",
      "105\n",
      "106\n",
      "107\n",
      "108\n",
      "109\n",
      "110\n",
      "111\n",
      "112\n",
      "113\n",
      "114\n",
      "115\n",
      "116\n",
      "117\n",
      "118\n",
      "119\n",
      "120\n",
      "121\n",
      "122\n",
      "123\n",
      "124\n",
      "125\n",
      "126\n",
      "127\n",
      "128\n",
      "129\n",
      "130\n",
      "131\n",
      "132\n",
      "133\n",
      "134\n",
      "135\n",
      "136\n",
      "137\n",
      "138\n",
      "139\n",
      "140\n",
      "141\n",
      "142\n",
      "143\n",
      "144\n",
      "145\n",
      "146\n",
      "147\n",
      "148\n",
      "149\n",
      "150\n",
      "151\n",
      "152\n",
      "153\n",
      "154\n",
      "155\n",
      "156\n",
      "157\n",
      "158\n",
      "159\n",
      "160\n",
      "161\n",
      "162\n",
      "163\n",
      "164\n",
      "165\n",
      "166\n",
      "167\n",
      "168\n",
      "169\n",
      "170\n",
      "171\n",
      "172\n",
      "173\n",
      "174\n",
      "175\n",
      "176\n",
      "177\n",
      "178\n",
      "179\n",
      "180\n",
      "181\n",
      "182\n",
      "183\n",
      "184\n",
      "185\n",
      "186\n",
      "187\n",
      "188\n",
      "189\n",
      "190\n",
      "191\n",
      "192\n",
      "193\n",
      "194\n",
      "195\n",
      "196\n",
      "197\n",
      "198\n",
      "199\n",
      "200\n",
      "201\n",
      "202\n",
      "203\n",
      "204\n",
      "205\n",
      "206\n",
      "207\n",
      "208\n",
      "209\n",
      "210\n",
      "211\n",
      "212\n",
      "213\n",
      "214\n",
      "215\n",
      "216\n",
      "217\n",
      "218\n",
      "219\n",
      "220\n",
      "221\n",
      "222\n",
      "223\n",
      "224\n",
      "225\n",
      "226\n",
      "227\n",
      "228\n",
      "229\n",
      "230\n",
      "231\n",
      "232\n",
      "233\n",
      "234\n",
      "235\n",
      "236\n",
      "237\n",
      "238\n",
      "239\n",
      "240\n",
      "241\n",
      "242\n",
      "243\n",
      "244\n",
      "245\n",
      "246\n",
      "247\n",
      "248\n",
      "249\n",
      "250\n",
      "251\n",
      "252\n",
      "253\n",
      "254\n",
      "255\n",
      "256\n",
      "257\n",
      "258\n",
      "259\n",
      "260\n",
      "261\n",
      "262\n",
      "263\n",
      "264\n",
      "265\n",
      "266\n",
      "267\n",
      "268\n",
      "269\n",
      "270\n",
      "271\n",
      "272\n",
      "273\n",
      "274\n",
      "275\n",
      "276\n",
      "277\n",
      "278\n",
      "279\n",
      "280\n",
      "281\n",
      "282\n",
      "283\n",
      "284\n",
      "285\n",
      "286\n",
      "287\n",
      "288\n",
      "289\n",
      "290\n",
      "291\n",
      "292\n",
      "293\n",
      "294\n",
      "295\n",
      "296\n",
      "297\n",
      "298\n",
      "299\n",
      "overall_mae 0.0808158578162201\n",
      "overall_fb tensor(1.0000)\n"
     ]
    }
   ],
   "source": [
    "overall_mae = 0\n",
    "total_prec = 0\n",
    "total_rec = 0\n",
    "for j in range(len(gt_paths)):\n",
    "\n",
    "        gt = np.array(Image.open(gt_paths[j]).convert('LA')) / 255\n",
    "        pred = np.array(Image.open(pred_paths[j]).convert('LA')) / 255 \n",
    "        mae = np.sum(np.abs(pred - gt)) / (pred.shape[:2][0] * pred.shape[:2][1])\n",
    "        \n",
    "        gt_arr = torch.from_numpy(np.array(gt)).float()\n",
    "        pred_arr = torch.from_numpy(np.array(pred)).float()\n",
    "        threshold = 216\n",
    "        y_pred = torch.ge(pred_arr, threshold).float()\n",
    "        y_true = torch.ge(gt_arr, 128).float()\n",
    "        y_true1 = torch.reshape(y_true, (1,-1))\n",
    "        y_pred1 = torch.reshape(y_pred, (1,-1))\n",
    "        \n",
    "        prec, rec = prec_rec(y_true1, y_pred1,0.3)\n",
    "\n",
    "        total_prec = total_prec + prec\n",
    "        total_rec = total_rec + rec\n",
    "\n",
    "        overall_mae = overall_mae + mae\n",
    "\n",
    "        print(j)\n",
    "\n",
    "beta2 = 0.3 \n",
    "overall_fb = (1+beta2) * (total_prec * total_rec) / ((beta2 * total_prec + total_rec) * len(gt_paths))\n",
    "print('overall_mae', overall_mae/300 )\n",
    "print('overall_fb', overall_fb)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "gt_paths = [...]  # Your ground truth paths\n",
    "pred_paths = [...]  # Your predicted paths"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "overall_mae 24.244757344866034\n",
      "overall_fb tensor(1.)\n"
     ]
    }
   ],
   "source": [
    "overall_mae = 0\n",
    "total_prec = 0\n",
    "total_rec = 0\n",
    "\n",
    "for j in range(len(gt_paths)):\n",
    "    gt = np.array(Image.open(gt_paths[j]).convert('L')) / 255\n",
    "    pred = np.array(Image.open(pred_paths[j]).convert('L')) / 255 \n",
    "\n",
    "    mae = np.sum(np.abs(pred - gt)) / (pred.shape[0] * pred.shape[1])\n",
    "        \n",
    "    gt_arr = torch.from_numpy(np.array(gt)).float()\n",
    "    pred_arr = torch.from_numpy(np.array(pred)).float()\n",
    "\n",
    "    # Iterate through thresholds to find max F-measure\n",
    "    max_fmeasure = 0\n",
    "    best_threshold = 0\n",
    "    for threshold in range(256):\n",
    "        y_pred = torch.ge(pred_arr, threshold).float()\n",
    "        y_true = torch.ge(gt_arr, 128).float()\n",
    "        y_true1 = torch.reshape(y_true, (1,-1))\n",
    "        y_pred1 = torch.reshape(y_pred, (1,-1))\n",
    "\n",
    "        prec, rec = prec_rec(y_true1, y_pred1, 0.3)\n",
    "\n",
    "        fmeasure = ((1 + 0.3) * prec * rec) / (0.3 * prec + rec)\n",
    "        if fmeasure > max_fmeasure:\n",
    "            max_fmeasure = fmeasure\n",
    "            best_threshold = threshold\n",
    "\n",
    "    # Use the best threshold to calculate precision and recall\n",
    "    y_pred = torch.ge(pred_arr, best_threshold).float()\n",
    "    y_true = torch.ge(gt_arr, 128).float()\n",
    "    y_true1 = torch.reshape(y_true, (1,-1))\n",
    "    y_pred1 = torch.reshape(y_pred, (1,-1))\n",
    "\n",
    "    prec, rec = prec_rec(y_true1, y_pred1, 0.3)\n",
    "\n",
    "    total_prec += prec\n",
    "    total_rec += rec\n",
    "    overall_mae += mae\n",
    "\n",
    "overall_prec = total_prec / len(gt_paths)\n",
    "overall_rec = total_rec / len(gt_paths)\n",
    "overall_fb = ((1 + 0.3) * overall_prec * overall_rec) / (0.3 * overall_prec + overall_rec)\n",
    "\n",
    "print('overall_mae', overall_mae )\n",
    "print('overall_fb', overall_fb )\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
